/**
 ******************************************************************************
 * @file           : bsp_rtc.h
 * @brief          : RTC Driver Header File (STM32H7xx)
 ******************************************************************************
 * @attention
 *
 * RTC驱动程序头文件
 * 提供实时时钟读写、日期时间管理等接口
 *
 ******************************************************************************
 */

/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __BSP_RTC_H
#define __BSP_RTC_H

#ifdef __cplusplus
extern "C" {
#endif

/* Includes ------------------------------------------------------------------*/
#include <stdint.h>
#include <time.h>

/* Exported types ------------------------------------------------------------*/
/**
 * @brief RTC错误码枚举
 */
typedef enum
{
    RTC_OK = 0,                 /*!< 成功 */
    RTC_ERROR_PARAM,            /*!< 参数错误 */
    RTC_ERROR_HAL               /*!< HAL库错误 */
} RTC_Error_e;

/**
 * @brief RTC日期时间结构体
 */
typedef struct
{
    uint16_t year;              /*!< 年(2000-2099) */
    uint8_t month;              /*!< 月(1-12) */
    uint8_t day;                /*!< 日(1-31) */
    uint8_t hour;               /*!< 时(0-23) */
    uint8_t minute;             /*!< 分(0-59) */
    uint8_t second;             /*!< 秒(0-59) */
    uint8_t week;               /*!< 星期(0-6, 0=周一) */
} RTC_DateTime_t;

/* Exported constants --------------------------------------------------------*/
/* Exported macro ------------------------------------------------------------*/
/* Exported variables --------------------------------------------------------*/
/* Exported functions --------------------------------------------------------*/

/**
 * @brief       RTC初始化
 *
 * @param       无
 *
 * @retval      无
 *
 * @note        初始化RTC外设和时钟源
 */
void rtc_init(void);

/**
 * @brief       RTC反初始化
 *
 * @param       无
 *
 * @retval      无
 *
 * @note        关闭RTC外设
 */
void rtc_deinit(void);

/**
 * @brief       设置日期时间
 *
 * @param[in]   datetime - 日期时间结构体指针
 *
 * @retval      RTC_Error_e - 错误码
 *
 * @note        设置年月日时分秒
 */
RTC_Error_e rtc_set_datetime(const RTC_DateTime_t *datetime);

/**
 * @brief       设置时间
 *
 * @param[in]   hour - 小时(0-23)
 * @param[in]   minute - 分钟(0-59)
 * @param[in]   second - 秒(0-59)
 *
 * @retval      RTC_Error_e - 错误码
 *
 * @note        只设置时间部分
 */
RTC_Error_e rtc_set_time(uint8_t hour, uint8_t minute, uint8_t second);

/**
 * @brief       设置日期
 *
 * @param[in]   year - 年(2000-2099)
 * @param[in]   month - 月(1-12)
 * @param[in]   day - 日(1-31)
 *
 * @retval      RTC_Error_e - 错误码
 *
 * @note        只设置日期部分
 */
RTC_Error_e rtc_set_date(uint16_t year, uint8_t month, uint8_t day);

/**
 * @brief       获取日期时间
 *
 * @param[out]  datetime - 日期时间结构体指针
 *
 * @retval      RTC_Error_e - 错误码
 *
 * @note        读取当前日期时间
 */
RTC_Error_e rtc_get_datetime(RTC_DateTime_t *datetime);

/**
 * @brief       获取时间
 *
 * @param[out]  hour - 小时指针
 * @param[out]  minute - 分钟指针
 * @param[out]  second - 秒指针
 *
 * @retval      RTC_Error_e - 错误码
 *
 * @note        只读取时间部分
 */
RTC_Error_e rtc_get_time(uint8_t *hour, uint8_t *minute, uint8_t *second);

/**
 * @brief       获取日期
 *
 * @param[out]  year - 年指针
 * @param[out]  month - 月指针
 * @param[out]  day - 日指针
 *
 * @retval      RTC_Error_e - 错误码
 *
 * @note        只读取日期部分
 */
RTC_Error_e rtc_get_date(uint16_t *year, uint8_t *month, uint8_t *day);

/**
 * @brief       获取Unix时间戳
 *
 * @param       无
 *
 * @retval      uint32_t - Unix时间戳(秒)
 *
 * @note        返回从1970年1月1日00:00:00起的秒数
 */
uint32_t rtc_get_timestamp(void);

/**
 * @brief       设置Unix时间戳
 *
 * @param[in]   timestamp - Unix时间戳(秒)
 *
 * @retval      RTC_Error_e - 错误码
 *
 * @note        从时间戳转换为日期时间
 */
RTC_Error_e rtc_set_timestamp(uint32_t timestamp);

/**
 * @brief       计算星期
 *
 * @param[in]   year - 年
 * @param[in]   month - 月
 * @param[in]   day - 日
 *
 * @retval      uint8_t - 星期(0-6, 0=周一)
 *
 * @note        使用Zeller公式计算
 */
uint8_t rtc_get_week(uint16_t year, uint8_t month, uint8_t day);

/**
 * @brief       判断闰年
 *
 * @param[in]   year - 年
 *
 * @retval      uint8_t - 1=闰年, 0=平年
 *
 * @note        无
 */
uint8_t rtc_is_leap_year(uint16_t year);

/**
 * @brief       打印日期时间
 *
 * @param       无
 *
 * @retval      无
 *
 * @note        用于调试，打印当前日期时间
 */
void rtc_print_datetime(void);

#ifdef __cplusplus
}
#endif

#endif /* __BSP_RTC_H */
